import base64
import io

from flask import Blueprint, request
import dashscope

import random
from http import HTTPStatus
import qrcode

from .user_info import get_user_info
from .feedback import get_feedback_by_device_id

from app.utils import json, str_split, get_current_time, get_current_seasons, get_position_by_ip

# https://dashscope.console.aliyun.com/overview
dashscope.api_key = "YOUR KEY"

api = Blueprint("api", __name__)

# 缓存当前设备已经推荐过的美食，每个设备id最多缓存20个;缓存格式：[{"device1": ["牛肉", "番茄", "土豆"]}, {"device2": {"清蒸鲈鱼"}}]
global_cache_food = []


@api.route("/v1/call", methods=["POST"])
def call():
    device_id = request.json.get("device_id")
    if device_id is None:
        return json(400, 'device_id is required', '')
    # 步数 单位：步
    step_count = request.json.get('step_count')
    # 血氧 单位：%
    spo2 = request.json.get('spo2')
    # 总卡路里 单位：千卡
    calories = request.json.get('calories')
    # 压力值
    stress = request.json.get('stress')
    # 睡眠时长
    sleep_duration = request.json.get('sleep_duration')
    # 温度
    temperature = request.json.get('temperature')
    # 自定义输入内容
    custom = request.json.get('custom')
    # 分类
    category = request.json.get('category')
    my_health_data = [
        # {'name': '步数', 'value': step_count, 'unit': '步'},
        {'name': '血氧', 'value': spo2, 'unit': '%'},
        {'name': '总卡路里', 'value': calories, 'unit': '千卡'},
        {'name': '压力值', 'value': stress, 'unit': ''},
        {'name': '睡眠时长', 'value': sleep_duration, 'unit': '小时'},
    ]
    # 获取客户端IP地址
    ip_addr = request.remote_addr
    if ip_addr == '127.0.0.1':
        position = '江苏 苏州'
    else:
        position = get_position_by_ip(ip_addr)

    prompt = gen_prompt(my_health_data, custom, position, temperature, device_id, category)
    response = ai_response(prompt)

    if response.status_code == HTTPStatus.OK:
        data = response.output.choices[0].message.content
        print(data)
        arr = format_data_to_arr(data, device_id)
        return json(200, 'ok', arr)
    else:
        # 处理出默认数据
        return json(500, response.message, {})


def ai_response(prompt):
    messages = [
        {'role': 'user', 'content': prompt}
    ]
    response = dashscope.Generation.call(
        model='qwen-turbo',
        messages=messages,
        seed=random.randint(1, 10000),
        result_format='message',
    )
    return response


def gen_prompt(my_health_data, custom, position, temperature, device_id, category):
    # 健康信息参考
    # health_info = get_health_info()
    # 我的健康数据内容（血氧：99%、总卡路里：200千卡、压力值：55、睡眠时长：6.5小时）
    my_health_str = ''
    for item in my_health_data:
        my_health_str += "{}：{}{}、".format(item['name'], item['value'], item['unit'])
    my_health_str = my_health_str[:-1]
    # 当前时间 h:i
    time = get_current_time()
    # 当前季节
    seasons = get_current_seasons()
    # 自定义内容
    custom_text = ''
    if custom != '':
        custom_text = "当然我还一些其他的要求：{}".format(custom)
    # 获取缓存
    food_names = get_cache(device_id)
    recommended_text = ''
    if food_names != '':
        recommended_text = '，过滤这些已经推荐过的菜肴：{}'.format(food_names)
        # 到达 20 清理缓存
        if len(food_names.split(',')) >= 20:
            clear_cache(device_id)
    print("已缓存：", food_names)
    # 个人信息
    user = get_user_info(device_id)
    print("user info :", user)
    user_text = ''
    if len(user) > 0:
        user_text = '基本信息：身高{}、体重{},'.format(user['height_range'], user['weight_range'])
    # 根据分类
    if category == '当地特色':
        category_text = '我现在位于{},当地气温{}摄氏度，我想吃当地最正宗的美食；'.format(position, temperature)
    elif category == '香辣四溢':
        category_text = '我特别喜欢香辣四溢的菜肴，常见的辣有香辣、麻辣、酸辣和卤辣我无辣不欢；'
    elif category == '甜润爽口':
        category_text = '我爱吃甜食，甜味美食，甜蜜诱惑，一口满足的感觉真的很不错，请务必帮我找甜食；'
    elif category == '美味肉食':
        category_text = '我无肉不欢，肉食者最爱，想吃美味肉食；'
    elif category == '健康素食':
        category_text = '我最爱健康的素食，既养生，又可以感受当季的味道，一定要给我推荐素食；'
    else:
        category_text = ''
    # 反馈内容
    like_names = get_feedback_by_device_id(device_id, 1)
    like_text = ''
    if len(like_names) > 0:
        like_food_names = ','.join(like_names)
        like_text = '，我喜欢的菜肴有：{}'.format(like_food_names)

    dislike_names = get_feedback_by_device_id(device_id, 2)
    dislike_text = ''
    if len(dislike_names) > 0:
        dislike_food_names = ','.join(dislike_names)
        dislike_text = '，注意我不喜欢：{}'.format(dislike_food_names)

    prompt = """
    你好！我想寻找一些既营养又美味的食物推荐。我很重视健康，但也希望能品尝到美味的食物。
    现在是{}{}，我的{}当前运动健康信息：{}，你对运动健康数据指标有一定的了解的。
    {}
    {}
    现在需要你根据我的这些综合因素帮我推荐一些营养丰富的菜肴，{}{}{}，
    回答格式示范：根据您的情况，推荐以下几种美食。\n\n1. 菜名：小炒肉\n描述：小炒肉是一道传统的中国菜肴，色泽诱人，口感鲜嫩，而且营养丰富，是家常菜中常见的一道下饭菜\n推荐等级：5。\n\n
    注意：推荐等级只能是整数：1-5，必须要有菜名。
""".format(seasons, time, user_text, my_health_str, category_text, custom_text, like_text, dislike_text,
           recommended_text)
    print(prompt)

    return prompt


def format_data_to_arr(data, device_id):
    arr = data.split('\n\n')
    for value in arr:
        if value == '':
            arr.remove(value)
    output_list = []
    names = []
    for item in arr:
        if item.find('\n') == -1:
            if item == '':
                item = '根据您的情况，推荐以下几种美食'
            output_list.append({'type': 1, 'title': item, 'name': '', 'desc': '', 'level': 0})
        else:
            item_arr = item.split('\n')
            if len(item_arr) >= 2:
                name = str_split(item_arr[0])
                # 保证取整
                level = str_split(item_arr[2])
                if not isinstance(level, int):
                    level = 4
                output_list.append({
                    'type': 2,
                    'title': '',
                    'name': name,
                    'desc': str_split(item_arr[1]),
                    'level': level
                })
                names.append(name)
    # 设置缓存
    set_cache(device_id, names)
    return output_list


# 获取缓存数据
def get_cache(device_id):
    global global_cache_food

    for item in global_cache_food:
        if device_id in item:
            return ",".join(item[device_id])

    return ""


# 设置缓存数据
def set_cache(device, food_list):
    global global_cache_food

    for item in global_cache_food:
        if device in item:
            # 每次累加数据
            item[device].extend(food_list)
            break
    else:
        global_cache_food.append({device: food_list})


# 清理缓存
def clear_cache(device_id):
    global global_cache_food
    to_remove = []
    for item in global_cache_food:
        if device_id in item:
            to_remove.append(item)
    for item in to_remove:
        global_cache_food.remove(item)


def get_health_info():
    health_info = """
    心率：心率是指心脏每分钟跳动的次数，是衡量心血管健康的重要指标之一。正常人在安静状态下的心率一般为60~100次/分钟。不同状态下心率会有所差异，如紧张、运动时心率会快，休息、睡觉时心率会慢；也可因年龄、性别或其他因素产生个体差异，如老年人偏慢，女性较男性稍快，运动员较普通人偏慢，心率可能低于50次/分钟。
    血氧饱和度：血氧饱和度（SpO₂）是血液中与氧气结合的血红蛋白占全部血红蛋白的比例, 即血液中血氧的浓度，它是人体机能正常运作的重要指标。通常情况下，血氧饱和度的正常水平范围是95%～100%。受身体因素或环境因素影响，血氧水平可能会低于正常值，这可能是身体异常的风险信号。
    压力值： 0-25 表示低压力水平，26-50 表示中等压力水平，51-75 和 76-100 分别表示高和极高压力水平 
    """
    return health_info


# 分享二维码
@api.route('/v1/share', methods=['GET'])
def share():
    food_name = request.args.get('food_name')
    if food_name == '':
        return json(400, 'food_name is required', '')

    url = ("https://h5.waimai.meituan.com/waimai/mindex/searchresults?queryType=12002&keyword={"
           "}&entranceId=0&qwTypeId=11002&mode=search").format(food_name)
    qrcode_base64 = gen_qrcode(url)

    return json(200, 'success', {'qrcode': qrcode_base64})


# 生成二维码
def gen_qrcode(text):
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_L,
        box_size=10,
        border=4,
    )
    qr.add_data(text)
    qr.make(fit=True)
    img = qr.make_image(fill_color="black", back_color="white")
    buf = io.BytesIO()
    img.save(buf)
    image_stream = buf.getvalue()
    hex_image = base64.b64encode(image_stream)
    base64_str = 'data:image/png;base64,' + hex_image.decode()
    return base64_str


# 获取美食详情
@api.route('/v1/getFoodDetails', methods=['POST', 'GET'])
def getFoodDetails():
    food_name = request.args.get('food_name')
    if food_name == '':
        return json(400, 'food_name is required', '')

    prompt = """
    你是美食届的百科全书，讲讲关于"{}"的介绍和相关故事
    """.format(food_name)
    response = ai_response(prompt)

    print(response)

    return json(200, 'success', {
        'image': '',
        'info': response.output.choices[0].message.content
    })
